<?php
/***************************************************************
*  Copyright notice
*  (c) 2009, jianyuzhu@gmail.com
*  All rights reserved
*  This script is part of the PPEMI project.
***************************************************************/

//User Session Class
class UserSession {
	var $sid;			//session id
	
	var $userid;		//user id
	var $username;		//user name
	var $usertype;		//user type, guest, virtual, customer, manager, admin
	var $usergid;		//user gid
	
	var $_st = 0;		//status check timestamp
	var $_sc = 0;		//status check fail count
	
	//constructor
	function UserSession($user = '', $sid = '') {
		if( $sid == '' ) {
			$this->sid = $this->_get_session_id();
		} else {
			$this->sid = $sid;
		}
		
		if( is_array($user) ) {
			$this->userid = $user['users_id'];
			$this->username = $user['users_name'];
			$this->usertype = $user['users_type'];
			$this->usergid = $user['users_gid'];
		} else {
			$this->userid = 0;
			$this->username = 'Guest';
			$this->usertype = 'guest';
			$this->usergid = 0;
		}
	}
	
	function reset() {
		$this->userid = 0;
		$this->username = 'Guest';
		$this->usertype = 'guest';
		$this->usergid = 0;
	}
	
	//methods
	function doLogin($data_array) {
		global $adb;
		
		$data_array = func_db_input($data_array);
		if( isset($data_array['username']) ) {
			$query = "select * from pp_users where users_name = '" . $data_array['username'] . "'";
		} elseif( isset($data_array['email_address']) ) {
			$query = "select * from pp_users where users_email_address = '" . $data_array['email_address'] . "'";
		} elseif( isset($data_array['uid']) ) {
			$query = "select * from pp_users where users_id = '" . $data_array['uid'] . "'";
		} else {
			return -99;
		}
		$password = $data_array['password'];
		if( isset($data_array['type']) ) {
			$query .= " and users_type = '" . $data_array['type'] . "'";
		}
		//
		$result = $adb->query($query);
		$user = $adb->fetch_array($result);
		if( is_array($user) && $user['users_id'] > 0 ) {
			if( $this->_validate_password($password, $user['users_password']) ) {
				//
				$this->doSession($user);
				
				return USER_LOGIN_SUCCESS;
			} else {
				return USER_LOGIN_PASSWORD_INVALID;
			}
		} else {
			return USER_LOGIN_INVALID;
		}
	}
	
	function doLogout($username = '') {
		$this->reset();
		$_SESSION['suser'] = $this;
	}
	
	function doRelogin() {
		return false;
	}
	
	function doSession($user) {
		if( is_array($user) && $user['users_id'] > 0 ) {
			$this->userid = $user['users_id'];
			$this->username = $user['users_name'];
			$this->usertype = $user['users_type'];
			$this->usergid = $user['users_gid'];
			
			//$_SESSION['suser'] = $this;
		}
	}
	
	function doConsistent() {
		$this->sid = $this->_get_session_id();
		
		//cookie
		if( CONST_CACHE_CONTROL_ENABLED == '1' ) {
			$ua = $_COOKIE['_pustatus'] ? 1 : 0;
			$ub = $this->userid > 0 ? 1 : 0;
			if( $ua & $ub == 0 ) {
				global $sessionObj;
				$sessionObj->setcookie('_pustatus', 1 - $ua);
			}
		}
	}
	
	//check
	function isLogin() {
		if( $this->userid > 0 ) {
			return true;
		}
		
		return false;
	}
	
	function isGuest() {
		if( $this->userid == 0 ) {
			return true;
		}
		
		return false;
	}
	
	function isAdmin() {
		if( $this->usertype == 'admin' ) {
			return true;
		}
		
		return false;
	}
	
	//private
	function _get_session_id() {
		global $sessionObj;
		
		if( $sessionObj->session_id ) {
			$sid = $sessionObj->session_id;
		} else {
			$sid = $GLOBALS['PPSID'];
			//$sid = $_COOKIE['PPSID'];
		}
		
		return $sid;
	}
	
	function _encryption_password($value) {
		include_once(CONFIG_PATH . CONFIG_DIR_FUNCTIONS . 'password_funcs.function.php');
		
		return func_encrypt_password($value);
	}
	
	function _validate_password($plain, $encrypted) {
		include_once(CONFIG_PATH . CONFIG_DIR_FUNCTIONS . 'password_funcs.function.php');
		
		return func_validate_password($plain, $encrypted);
	}
}

//User Base Class
//Core User
class UserBase extends Base {
	//format
	//	0	no format
	//	1	one
	//	2	more
	var $_format_type = 0;
	
	//constructor
	function UserBase() {
		parent::Base();
		
		$this->_format_type = defined('CONST_USER_FORMAT_TYPE') ? CONST_USER_FORMAT_TYPE : 0;
	}
	
	//Session
	function doLogin($data_array) {
		if( USER_LOGIN_CHECK_TIMES > 0 && $_SESSION['suser']->_sc >= USER_LOGIN_CHECK_TIMES ) {
			return USER_LOGIN_INVALID_HACK;
		}
		//
		if( strstr(CONST_SECURITY_LOGIN_TYPE, CONST_SECURITY_LOGIN_EMAIL) !== false ) {
			if( strstr($data_array['username'], '@') !== false ) {
				$data_array['email_address'] = $data_array['username'];
				unset($data_array['username']);
			}
		}
		//
		$data_array = func_db_input($data_array);
		if( isset($data_array['username']) ) {
			$query = "select * from pp_users where users_name = '" . $data_array['username'] . "'";
		} elseif( isset($data_array['email_address']) ) {
			$query = "select * from pp_users where users_email_address = '" . $data_array['email_address'] . "'";
		} elseif( isset($data_array['uid']) ) {
			$query = "select * from pp_users where users_id = '" . $data_array['uid'] . "'";
		} else {
			return USER_LOGIN_USERNAME_INVALID;
		}
		$password = $data_array['password'];
		if( isset($data_array['type']) ) {
			$query .= " and users_type = '" . $data_array['type'] . "'";
		}
		//
		$result = $this->adb->query($query);
		$user = $this->adb->fetch_array($result);
		if( is_array($user) && $user['users_id'] > 0 ) {
			if( $user['users_status'] == 0 ) {
				return USER_LOGIN_CLOSED;
			} elseif( $this->_validate_password($password, $user['users_password']) ) {
				$this->doSyncUser($user);
				$_SESSION['user_login'] = 'true';
				
				//update
				$this->doLoginUpdate();
				$this->doLoginUpdateTime();
				
				//cookie
				if( CONST_CACHE_CONTROL_ENABLED == '1' ) {
					global $sessionObj;
					$sessionObj->setcookie('_pustatus', 1);
					$sessionObj->setcookie('_puname', rawurlencode($_SESSION['suser']->username));
					$sessionObj->setcookie('_pucompany', rawurlencode($_SESSION['suser']->company));
				}
				
				//log
				$this->addLog('login');
				
				return USER_LOGIN_SUCCESS;
			} else {
				$_SESSION['suser']->_sc++;
				
				return USER_LOGIN_PASSWORD_INVALID;
			}
		} else {
			$_SESSION['suser']->_sc++;
			
			return USER_LOGIN_INVALID;
		}
	}
	
	function doLoginNoCheck($user) {
		$this->doSyncUser($user);
		$_SESSION['user_login'] = 'true';
		
		//update
		$this->doLoginUpdate();
		$this->doLoginUpdateTime();
		
		return USER_LOGIN_SUCCESS;
	}
	
	function doLogout($username = '') {
		//log
		$this->addLog('logout');
		
		//cookie
		if( CONST_CACHE_CONTROL_ENABLED == '1' ) {
			global $sessionObj;
			$sessionObj->setcookie('_pustatus', 0);
		}
		
		//
		$_SESSION['suser']->reset();
		$_SESSION['user_login'] = 'false';
	}
	
	function doRelogin($data_array) {
		return $this->doLogin($data_array);
	}
	
	function doSyncUser($user) {
		if( is_array($user) && $user['users_id'] > 0 ) {
			$_SESSION['suser']->userid = $user['users_id'];
			$_SESSION['suser']->firstname = $user['users_firstname'];
			$_SESSION['suser']->lastname = $user['users_lastname'];
			$_SESSION['suser']->username = $user['users_name'];
			$_SESSION['suser']->usertype = $user['users_type'];
			$_SESSION['suser']->usergid = $user['users_gid'];
			
			$_SESSION['suser']->resell = $user['users_resell'];
			$_SESSION['suser']->usercid = $this->getUserCategoryID($user['users_id']);
			$_SESSION['suser']->discount = $this->getUserDiscount($user['users_id'], 0, $user['users_discount']);
			$_SESSION['suser']->gcode = $this->getUserGroupCode($user['users_id']);
			$_SESSION['suser']->company = $this->getUserCompany($user['users_id']);
			
			if( CONST_PRICE_MODE_TYPE == CONST_PRICE_MODE_UCT ) {
				$_SESSION['suser']->pricetypes = $this->getUserPriceTypes($user['users_id']);
			}
		}
	}
	
	function doConsistent() {
		$_SESSION['suser']->sid = $this->_get_session_id();
	}
	
	function doLoginUpdate() {
		$current_time = time();
		$_SESSION['suser']->nexttime = $current_time + 600;
		$user = $this->getUser($_SESSION['suser']->userid);
		$logintotaltime = $user['users_logintotaltime'] + 1800;
		
		$data_array = array(
				'users_lastvisit' => $current_time,
				'users_lastaction' => 'login',
				'users_lastip' => util_get_ip_address(),
				'users_lastlogin' => 'now()',
				'users_logintimes' => 'add_one()',
				'users_logintotaltime' => $logintotaltime,
					);
		
		return $this->adb->updateA('pp_users', $data_array, "users_id = '" . (int)$_SESSION['suser']->userid . "'");
	}
	
	function doLoginUpdateTime() {
		$current_time = time();
		if( $_SESSION['suser']->userid > 0 && $_SESSION['suser']->nexttime < $current_time ) {
			$user = $this->getUser($_SESSION['suser']->userid);
			$logintotaltime = $user['users_logintotaltime'] + 600;
			$data_array = array(
					'users_logintotaltime' => $logintotaltime,
						);
			$this->adb->updateA('pp_users', $data_array, "users_id = '" . (int)$_SESSION['suser']->userid . "'");
			$_SESSION['suser']->nexttime = $current_time + 1800;
		}
	}
	
	//check
	function isLogin() {
		if( $_SESSION['suser']->userid > 0 ) {
			return true;
		}
		
		return false;
	}
	
	function isGuest() {
		if( $_SESSION['suser']->userid == 0 ) {
			return true;
		}
		
		return false;
	}
	
	function isAdmin() {
		if( $_SESSION['suser']->usertype == 'admin' ) {
			return true;
		}
		
		return false;
	}
	
	//methods
	function getUser($value, $type = 'users_id') {
		$value = func_db_input($value);
		
		if( $type == 'users_name' || $type == 'username' ) {
			$query = "select * from pp_users where users_name = '" . $value . "'";
		} elseif( $type == 'users_email_address' || $type == 'email_address' || $type == 'email' ) {
			$query = "select * from pp_users where users_email_address = '" . $value . "'";
		} elseif( $type == 'users_id' || $type == 'uid' || $type == 'id' ) {
			$query = "select * from pp_users where users_id = '" . (int)$value . "'";
		} else {
			$query = "select * from pp_users where users_id = '" . (int)$value . "'";
		}
		
		$row = $this->adb->getRow($query);
		unset($row['users_password']);
		
		//format
		if( $this->_format_type >= 1 ) {
			$row = $this->_format_handler($row);
		}
		
		return $row;
	}
	
	function getUserDetail($value, $type = 'users_id') {
		$value = func_db_input($value);
		
		if( $type == 'users_name' || $type == 'username' ) {
			$query = "select u.*, ug.* from pp_users u, pp_users_groups ug, pp_users_to_groups u2g " 
					. " where u.users_id = u2g.users_id and u2g.groups_id = ug.groups_id and u.users_name = '" . $value . "'";
		} elseif( $type == 'users_id' || $type == 'uid' || $type == 'id' ) {
			$query = "select u.*, ug.* from pp_users u, pp_users_groups ug, pp_users_to_groups u2g " 
					. " where u.users_id = u2g.users_id and u2g.groups_id = ug.groups_id and u.users_id = '" . (int)$value . "'";
		} else {
			$query = "select u.*, ug.* from pp_users u, pp_users_groups ug, pp_users_to_groups u2g " 
					. " where u.users_id = u2g.users_id and u2g.groups_id = ug.groups_id and u.users_id = '" . (int)$value . "'";
		}
		
		$row = $this->adb->getRow($query);
		unset($row['users_password']);
		
		//format
		if( $this->_format_type >= 1 ) {
			$row = $this->_format_handler($row);
		}
		
		return $row;
	}
	
	function getUserID($value, $type = 'users_name') {
		$value = func_db_input($value);
		if( $type == 'users_name' || $type == 'username' ) {
			$query = "select users_id from pp_users where users_name = '" . $value . "'";
		} elseif( $type == 'users_email_address' || $type == 'email_address' || $type == 'email' ) {
			$query = "select users_id from pp_users where users_email_address = '" . $value . "'";
		} else {
			return '0';
		}
		
		$row = $this->adb->getRow($query);
		if( $row['users_id'] > 0 ) {
			return $row['users_id'];
		}
		
		return '0';
	}
	
	function getUserPassword($value, $type = 'users_name') {
		$value = func_db_input($value);
		if( $type == 'users_name' || $type == 'username' ) {
			$query = "select users_password from pp_users where users_name = '" . $value . "'";
			
			return $this->adb->getRow($query, 'users_password');
		} elseif( $type == 'users_email_address' || $type == 'email_address' || $type == 'email' ) {
			$query = "select users_password from pp_users where users_email_address = '" . $value . "'";
			
			return $this->adb->getRow($query, 'users_password');
		} elseif( $type == 'users_id' || $type == 'uid' || $type == 'id' ) {
			$query = "select users_password from pp_users where users_id = '" . $value . "'";
			
			return $this->adb->getRow($query, 'users_password');
		} else {
			return '';
		}
	}
	
	function getUserCompany($users_id) {
		$row = $this->adb->getRow("select address_company from pp_users_address where users_id = '" . (int)$users_id . "' and address_type = 'address'");
		
		return $row['address_company'];
	}
	
	function getUserCreditLine($users_id) {
		$row = $this->adb->getRow("select users_creditline from pp_users where users_id = '" . (int)$users_id . "'");
		
		return $row['users_creditline'];
	}
	
	function getUserCreditLineUsed($users_id) {
		if( $users_id == 0 ) {
			return 0;
		}
		$uacctObj = $this->_get_uacctObj($users_id);
		
		$amount = $uacctObj->getAmount('', 5);
		
		return $amount;
	}
	
	function getUserCreditLineUsage($users_id, $price = 0) {
		if( $users_id == 0 ) {
			return 0;
		}
		$uacctObj = $this->_get_uacctObj($users_id);
		
		$amount = $uacctObj->getCreditLineUsage($price);
		
		return $amount;
	}
	
	function getUserCreditLineUsable($users_id, $price = 0) {
		if( $users_id == 0 ) {
			return 0;
		}
		$uacctObj = $this->_get_uacctObj($users_id);
		
		return $uacctObj->getCreditLineUsable($price);
	}
	
	function _get_uacctObj($users_id) {
		include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'user.account.class.php');
		$uacctObj = new UserAccountBase();
		$uacctObj->owner = $users_id;
		
		return $uacctObj;
	}
	
	//address
	function getAddress($address_id, $users_id = '') {
		$query = "select * from pp_users_address where address_id = '" . (int)$address_id . "' ";
		if( $users_id != '' ) {
			$query .= " and users_id = '" . (int)$users_id . "' ";
		}
		
		return $this->adb->getRow($query);
	}
	
	function bindAddressDetail($address) {
		if( $address['address_zones_id'] > 0 ) {
			include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'core.zone.class.php');
			$zoneObj = new CoreZone();
			$zone = $zoneObj->getZoneA($address['address_zones_id']);
			$address['zone'] = $zone;
			$address['address_state'] = $zone['zones_code'];
		}
		if( $address['address_countries_id'] > 0 ) {
			include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'core.country.class.php');
			$countryObj = new CoreCountry();
			$country = $countryObj->getCountryA($address['address_countries_id']);
			$address['country'] = $country;
			$address['address_country'] = $country['countries_name'];
		}
		
		return $address;
	}
	
	function getUserAddress($users_id, $address_id = '', $type = '') {
		$query = "select ua.*, z.*, c.*, " 
				. " if(ua.address_zones_id > 0, z.zones_name, ua.address_state) as statename, " 
				. " if(ua.address_zones_id > 0, z.zones_code, ua.address_state) as statecode, " 
				. " if(ua.address_countries_id > 0, c.countries_name, ua.address_country) as countryname, " 
				. " if(ua.address_countries_id > 0, c.countries_iso_code_3, ua.address_country) as countrycode " 
				. " from pp_users_address ua left join pp_zones z on ua.address_zones_id = z.zones_id " 
				. " left join pp_countries c on ua.address_countries_id = c.countries_id " 
				. " where ua.users_id = '" . (int)$users_id . "'";
		if( $address_id > 0 ) {
			$query .= " and ua.address_id = '" . (int)$address_id . "'";
		}
		if( $type != '' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		}
		
		return $this->adb->getRow($query);
	}
	
	function getUserAddressID($users_id, $address_id = '', $type = '') {
		$address = $this->getUserAddress($users_id, $address_id, $type);
		
		return $address['address_id'];
	}
	
	//address, shipping, billing, payment
	function getUsersAddress($users_ids, $type = '') {
		$query = "select ua.*, z.*, c.*, " 
				. " if(ua.address_zones_id > 0, z.zones_name, ua.address_state) as statename, " 
				. " if(ua.address_zones_id > 0, z.zones_code, ua.address_state) as statecode, " 
				. " if(ua.address_countries_id > 0, c.countries_name, ua.address_country) as countryname, " 
				. " if(ua.address_countries_id > 0, c.countries_iso_code_3, ua.address_country) as countrycode " 
				. " from pp_users_address ua left join pp_zones z on ua.address_zones_id = z.zones_id " 
				. " left join pp_countries c on ua.address_countries_id = c.countries_id " 
				. " where ua.users_id in (" . $this->_implode(',', $users_ids) . ") ";
		if( $type != '' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		}
		$query .= " group by ua.users_id ";
		
		return $this->adb->getRows($query);
	}
	
	//
	function getUserDefaultAddress($users_id, $type = '') {
		$query = "select ua.* from pp_users_address ua, pp_users u " 
				. " where ua.users_id = u.users_id and u.users_id = '" . (int)$users_id . "' ";
		
		if( $type == 'address' ) {
			$query .= " and (ua.address_id = u.users_default_address or u.users_default_address = 0)" 
					. " and ua.address_type = 'address'";
		} elseif( $type == 'ship' || $type == 'shipping' ) {
			$query .= " and (ua.address_id = u.users_default_shipping_address or u.users_default_shipping_address = 0)" 
					. " and ua.address_type = 'shipping'";
		} elseif( $type == 'bill' || $type == 'billing' ) {
			$query .= " and (ua.address_id = u.users_default_billing_address or u.users_default_billing_address = 0)" 
					. " and ua.address_type = 'billing'";
		} elseif( $type == 'payment' ) {
			$query .= " and (ua.address_id = u.users_default_billing_address or u.users_default_billing_address = 0)" 
					. " and ua.address_type = 'payment'";
		} else {
			$query .= " and (ua.address_id = u.users_default_address or u.users_default_address = 0)";
		}
		$row = $this->adb->getRow($query);
		if( $row['address_id'] > 0 ) {
			return $row;
		} else {
			return $this->getUserDefaultAddressA($users_id, $type);
		}
	}
	
	function getUserDefaultAddressA($users_id, $type = '') {
		$query = "select ua.* from pp_users_address ua, pp_users u " 
				. " where ua.users_id = u.users_id and u.users_id = '" . (int)$users_id . "' " 
				. " and (ua.address_id = u.users_default_address or u.users_default_address = 0)";
		$row = $this->adb->getRow($query);
		
		return $row;
	}
	
	function getUserDefaultAddressID($users_id, $type = '') {
		$row = $this->getUserDefaultAddress($users_id, $type);
		if( $row['address_id'] > 0 ) {
			return $row['address_id'];
		} else {
			return $this->getUserDefaultAddressIDA($users_id, $type);
		}
	}
	
	function getUserDefaultAddressIDA($users_id, $type = '') {
		$query = "select u.users_default_address, u.users_default_shipping_address, u.users_default_billing_address, ua.address_id " 
				. " from pp_users u left join pp_users_address ua on u.users_id = ua.users_id " 
				. " where u.users_id = '" . (int)$users_id . "' and ua.address_type = ''";
		$row = $this->adb->getRow($query);
		
		if( $type == 'all' ) {
			$address = array(
					'address' => ($row['users_default_address'] > 0) ? $row['users_default_address'] : $row['address_id'],
					'shipping' => ($row['users_default_shipping_address'] > 0) ? $row['users_default_shipping_address'] : $row['address_id'],
					'billing' => ($row['users_default_billing_address'] > 0) ? $row['users_default_billing_address'] : $row['address_id'],
						);
		} elseif( $type == 'address' && $row['users_default_address'] > 0 ) {
			return $row['users_default_address'];
		} elseif( ($type == 'ship' || $type == 'shipping') && $row['users_default_shipping_address'] > 0 ) {
			return $row['users_default_shipping_address'];
		} elseif( ($type == 'bill' || $type == 'billing') && $row['users_default_billing_address'] > 0 ) {
			return $row['users_default_billing_address'];
		} else {
			return $row['address_id'];
		}
	}
	
	function getUserAddresses($users_id, $type = '') {
		$query = "select ua.*, z.*, c.*, " 
				. " if(ua.address_zones_id > 0, z.zones_name, ua.address_state) as statename, " 
				. " if(ua.address_zones_id > 0, z.zones_code, ua.address_state) as statecode, " 
				. " if(ua.address_countries_id > 0, c.countries_name, ua.address_country) as countryname, " 
				. " if(ua.address_countries_id > 0, c.countries_iso_code_3, ua.address_country) as countrycode " 
				. " from pp_users_address ua left join pp_zones z on ua.address_zones_id = z.zones_id " 
				. " left join pp_countries c on ua.address_countries_id = c.countries_id " 
				. " where ua.users_id = '" . (int)$users_id . "'";
		
		//
		if( $type == 'shipping' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		} elseif( $type == 'billing' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		} elseif( $type == 'address' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		} elseif( $type == 'profile' ) {
			$query .= " and ua.address_type = '" . $type . "'";
		} else {
			//
		}
		
		//
		$result = $this->adb->query($query);
		while($row = $this->adb->fetch_array($result)) {
			$rows[] = $row;
		}
		
		return $rows;
	}
	
	function getUserAddressCount($users_id, $type = 'shipping') {
		$query = "select count(*) as count from pp_users_address where users_id = '" . (int)$users_id . "'";
		//
		if( $type == 'ship' || $type == 'shipping' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'bill' || $type == 'billing' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'address' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'profile' ) {
			$query .= " and address_type = '" . $type . "'";
		} else {
			//
		}
		
		return $this->adb->getCount($query);
	}
	
	function getUserAddressBooks($users_id, $type = '') {
		$query = "select address_id, address_name, address_contactname, address_firstname, address_lastname from pp_users_address "
				. " where users_id = '" . (int)$users_id . "'";
		
		//
		if( $type == 'shipping' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'billing' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'address' ) {
			$query .= " and address_type = '" . $type . "'";
		} elseif( $type == 'profile' ) {
			$query .= " and address_type = '" . $type . "'";
		} else {
			//
		}
		
		//
		$result = $this->adb->query($query);
		while($row = $this->adb->fetch_array($result)) {
			if( $this->_not_null($row['address_name']) ) {
				$rows[$row['address_id']] = $row['address_name'];
			} elseif( $this->_not_null($row['address_name']) ) {
				$rows[$row['address_id']] = $row['address_contactname'];
			} else {
				$rows[$row['address_id']] = $row['address_firstname'] . ' ' . $row['address_lastname'];
			}
		}
		
		return $rows;
	}
	
	function getUserAddressList($addresses, $type = '') {
		$list = array();
		for($i=0, $n=sizeof($addresses); $i<$n; $i++) {
			if( $type == '' || $addresses[$i]['address_type'] == $type ) {
				$list[] = $addresses[$i];
			}
		}
		
		return $list;
	}
	
	function getUserAddressListBooks($addresses, $type = '') {
		$books = array();
		for($i=0, $n=sizeof($addresses); $i<$n; $i++) {
			if( $type == '' || $addresses[$i]['address_type'] == $type ) {
				if( $this->_not_null($addresses[$i]['address_name']) ) {
					$books[$addresses[$i]['address_id']] = $addresses[$i]['address_name'];
				} elseif( $this->_not_null($addresses[$i]['address_name']) ) {
					$books[$addresses[$i]['address_id']] = $addresses[$i]['address_contactname'];
				} else {
					$books[$addresses[$i]['address_id']] = $addresses[$i]['address_firstname'] . ' ' . $addresses[$i]['address_lastname'];
				}
			}
		}
		
		return $books;
	}
	
	function getUserInfo($users_id) {
		$query = "select * from pp_users where users_id = '" . (int)$users_id . "'";
		$row = $this->adb->getRow($query);
		
		return $row;
	}
	
	//check
	function checkUserStatus($value, $type = 'users_name') {
		$value = func_db_input($value);
		
		if( $type == 'users_id' || $type == 'uid' || $type == 'id' ) {
			$query = "select count(*) as count from pp_users where users_id = '" . (int)$value . "'";
		} elseif( $type == 'users_name' || $type == 'username' ) {
			$query = "select count(*) as count from pp_users where users_name = '" . $value . "'";
		} else {
			return false;
		}
		$row = $this->adb->getRow($query);
		
		if( $row['count'] == '1' ) {
			return true;
		} else {
			return false;
		}
	}
	
	function checkPassword($users_id, $password) {
		$password = func_db_input($password);
		
		$query = "select * from pp_users where users_id = '" . (int)$users_id . "'";
		$row = $this->adb->getRow($query);
		
		if( $this->_validate_password($password, $row['users_password']) ) {
			return true;
		} else {
			return false;
		}
	}
	
	function checkUsername($users_name, $except_uid = '') {
		$users_name = func_db_input($users_name);
		
		$parameters = "users_name = '" . $users_name . "'";
		if( $except_uid != '' ) {
			$parameters .= " and users_id != '" . (int)$except_uid . "'";
		}
		$count = $this->adb->getCountA('pp_users', $parameters);
		
		return (($count > 0) ? true : false);
	}
	
	function checkUserEmail($users_email_address, $except_uid = '') {
		$users_email_address = func_db_input($users_email_address);
		
		$parameters = "users_email_address = '" . $users_email_address . "'";
		if( $except_uid != '' ) {
			$parameters .= " and users_id != '" . (int)$except_uid . "'";
		}
		$count = $this->adb->getCountA('pp_users', $parameters);
		
		return (($count > 0) ? true : false);
	}
	
	function checkUserAddress($users_id, $address_id) {
		$query = "select count(*) as count from pp_users_address where users_id = '" . (int)$users_id . "' and address_id = '" . (int)$address_id . "'";
		$result = $this->adb->query($query);
		$row = $this->adb->fetch_array($result);
		
		if( $row['count'] == '1' ) {
			return true;
		} else {
			return false;
		}
	}
	
	function checkPermission($code, $users_id = '') {
		if( $users_id == '' ) $users_id = $this->_get_current_user();
		
		$query = "select count(*) as count from pp_users u, pp_users_to_groups u2g, pp_users_permissions up, pp_users_roles ur " 
				. " where u.users_id = '" . (int)$users_id . "' " 
				. " and u.users_id = u2g.users_id and u2g.groups_id = up.groups_id " 
				. " and up.roles_id = ur.roles_id and ur.roles_code = '" . $code . "' and up.permission = '1'";
		$count = $this->adb->getCount($query);
		
		return (($count > 0) ? true : false);
	}
	
	function checkGroupPermission($group, $users_id = '') {
		if( $users_id == '' ) $users_id = $this->_get_current_user();
		
		$query = "select count(*) as count from pp_users u, pp_users_to_groups u2g, pp_users_permissions up, pp_users_roles ur " 
				. " where u.users_id = '" . (int)$users_id . "' " 
				. " and u.users_id = u2g.users_id and u2g.groups_id = up.groups_id " 
				. " and up.roles_id = ur.roles_id and ur.roles_group = '" . $group . "' and up.permission = '1'";
		$count = $this->adb->getCount($query);
		
		return (($count > 0) ? true : false);
	}
	
	function checkUserPermission($users_id, $code) {
		return $this->checkPermission($code, $users_id);
	}
	
	//Current User
	function getCurrentUser() {
		if( $this->_check_user_authority() ) {
			return $this->getUser($this->_get_current_user());
		}
		
		return false;
	}
	
	function getCurrentUserDetail() {
		if( $this->_check_user_authority() ) {
			return $this->getUserDetail($this->_get_current_user());
		}
		
		return false;
	}
	
	function getCurrentUserDiscount() {
		return $_SESSION['suser']->discount;
	}
	
	function updateCurrentUser($data_array) {
		if( $this->_check_user_authority() ) {
			return $this->updateUser($this->_get_current_user(), $data_array);
		}
		
		return false;
	}
	
	//add filter
	function _set_group($groups_id, $type = 'customer') {
		if( $groups_id == 0 ) {
			$groups_id = CONST_DEFAULT_USER_GROUP;
		}
		
		return $groups_id;
	}
	
	function _set_category($categories_id, $type = 'customer') {
		if( $categories_id == 0 ) {
			$categories_id = CONST_DEFAULT_USER_CATEGORY;
		}
		
		return $categories_id;
	}
	
	function addUser($data_array) {
		$data_array = func_db_input($data_array);
		
		$data_array['users_password'] = $this->_encryption_password($data_array['users_password']);
		$data_array['users_date_added'] = 'now()';
		$data_array['users_added_by'] = $this->_get_current_user();
		$data_array['users_status'] = '1';
		
		$users_id = $this->_insert('pp_users', $data_array);
		
		if( !isset($data_array['users_name']) || $data_array['users_name'] == '' ) {
			$this->_update_account($users_id);
		}
		
		return $users_id;
	}
	
	function addUserA($data_array, $type = 'customer') {
		$data_array['users_type'] = $type;
		$users_id = $this->addUser($data_array);
		
		//address
		$this->addAddress($users_id, $data_array);
		
		//permission
		$data_array['groups_id'] = $this->_set_group($data_array['groups_id'], $type);
		$data_array['categories_id'] = $this->_set_category($data_array['categories_id'], $type);
		$this->_add('pp_users_to_groups', array('users_id' => $users_id, 'groups_id' => $data_array['groups_id']));
		$this->_add('pp_users_to_categories', array('users_id' => $users_id, 'categories_id' => $data_array['categories_id']));
		
		return $users_id;
	}
	
	function addUserB($data_array, $type = 'customer') {
		$data_array['users_type'] = $type;
		$users_id = $this->addUser($data_array);
		
		//permission
		$data_array['groups_id'] = $this->_set_group($data_array['groups_id'], $type);
		$data_array['categories_id'] = $this->_set_category($data_array['categories_id'], $type);
		$this->_add('pp_users_to_groups', array('users_id' => $users_id, 'groups_id' => $data_array['groups_id']));
		$this->_add('pp_users_to_categories', array('users_id' => $users_id, 'categories_id' => $data_array['categories_id']));
		
		return $users_id;
	}
	
	function addUserF($data_array, $type = 'customer') {
		$data_array['users_type'] = $type;
		$users_id = $this->addUser($data_array);
		
		$data_array['users_id'] = $users_id;
		$this->_add('pp_users_address', $data_array);
		
		//permission
		$data_array['groups_id'] = $this->_set_group($data_array['groups_id'], $type);
		$data_array['categories_id'] = $this->_set_category($data_array['categories_id'], $type);
		$this->_add('pp_users_to_groups', array('users_id' => $users_id, 'groups_id' => $data_array['groups_id']));
		$this->_add('pp_users_to_categories', array('users_id' => $users_id, 'categories_id' => $data_array['categories_id']));
		
		return $users_id;
	}
	
	function updateUser($users_id, $data_array) {
		$data_array = func_db_input($data_array);
		
		$data_array['users_last_modified'] = 'now()';
		$data_array['users_modified_by'] = $this->_get_current_user();
		
		return $this->_update('pp_users', $data_array, "users_id = '" . (int)$users_id . "'");
	}
	
	function updateUserType($users_id, $type = 'customer') {
		return $this->adb->update("update pp_users set users_type = '" . $type . "' where users_id = '" . (int)$users_id . "'");
	}
	
	function updateUserStatus($users_id, $status = 1) {
		if( $status != 1 ) {
			$status = 0;
		}
		return $this->adb->update("update pp_users set users_status = '" . (int)$status . "' where users_id = '" . (int)$users_id . "'");
	}
	
	function updatePassword($users_id, $password) {
		$password = func_db_input($password);
		$password = $this->_encryption_password($password);
		
		$query = "update pp_users set users_password = '" . $password . "' where users_id = '" . (int)$users_id . "'";
		return $this->adb->update($query);
	}
	
	function updateNotification($users_id = '', $value = 1) {
		if( $users_id == '' ) {
			$users_id = $this->_get_current_user();
		}
		$query = "update pp_users set users_notification = '" . (int)$value . "' where users_id = '" . (int)$users_id . "'";
		
		return $this->adb->update($query);
	}
	
	function updateSubscription($users_id = '', $value = 1) {
		if( $users_id == '' ) {
			$users_id = $this->_get_current_user();
		}
		$query = "update pp_users set users_subscription = '" . (int)$value . "' where users_id = '" . (int)$users_id . "'";
		
		return $this->adb->update($query);
	}
	
	function updateUsers($users_ids, $data_array) {
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->_update('pp_users', $data_array, "users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				$this->_update('pp_users', $data_array, "users_id in (" . $query_ids . ")");
			}
		}
	}
	
	function updateUsersF($users_ids, $field, $value = '') {
		if( $field == 'top' ) {
			$query_str = " users_top = '1' ";
		} elseif( $field == 'untop' ) {
			$query_str = " users_top = '0' ";
		} elseif( $field == 'recommend' ) {
			$query_str = " users_recommend = '1' ";
		} elseif( $field == 'unrecommend' ) {
			$query_str = " users_recommend = '0' ";
		} elseif( $field == 'public' ) {
			$query_str = " users_public = '1' ";
		} elseif( $field == 'unpublic' ) {
			$query_str = " users_public = '0' ";
		} elseif( $field == 'level' ) {
			$query_str = " users_level = '" . (int)$value . "' ";
		} elseif( $field == 'unlevel' ) {
			$query_str = " users_level = '0' ";
		} else {
			return;
		}
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->adb->update("update pp_users set $query_str where users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				$this->adb->update("update pp_users set $query_str where users_id in (" . $query_ids . ")");
			}
		}
	}
	
	function updateUsersGroup($users_ids, $groups_id) {
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->adb->update("update pp_users_to_groups set groups_id = '" . (int)$groups_id . "' where users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				return $this->adb->update("update pp_users_to_groups set groups_id = '" . (int)$groups_id . "' where users_id in (" . $query_ids . ")");
			}
		}
	}
	
	function updateGroupUserstoNewGroup($groups_id, $groups_id_new) {
		return $this->adb->update("update pp_users_to_groups set groups_id = '" . (int)$groups_id_new . "' where groups_id = '" . (int)$groups_id . "'");
	}
	
	function updateUsersCategory($users_ids, $categories_id) {
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->adb->update("update pp_users_to_categories set categories_id = '" . (int)$categories_id . "' where users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				return $this->adb->update("update pp_users_to_categories set categories_id = '" . (int)$categories_id . "' where users_id in (" . $query_ids . ")");
			}
		}
	}
	
	function updateCategoryUserstoNewCategory($categories_id, $categories_id_new) {
		$query = "update pp_users_to_categories set categories_id = '" . (int)$categories_id_new . "' where categories_id = '" . (int)$categories_id . "'";
		
		return $this->adb->update($query);
	}
	
	function deleteUser($users_id) {
		$query = "delete from pp_users where users_id = '" . (int)$users_id . "'";
		$result = $this->adb->query($query);
		$query = "delete from pp_users_address where users_id = '" . (int)$users_id . "'";
		$result = $this->adb->query($query);
		$query = "delete from pp_users_to_categories where users_id = '" . (int)$users_id . "'";
		$result = $this->adb->query($query);
		$query = "delete from pp_users_to_groups where users_id = '" . (int)$users_id . "'";
		$result = $this->adb->query($query);
		
		return true;
	}
	
	function deleteUsers($users_ids) {
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->adb->deleteA('pp_users', "users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				$this->adb->deleteA('pp_users', "users_id in (" . $query_ids . ")");
			}
		}
	}
	
	function deleteGroupUsers($groups_id) {
		$query = "delete pp_users, pp_users_to_groups from pp_users u, pp_users_to_groups u2g " 
				. " where u.users_id = u2g.users_id and u2g.groups_id = '" . (int)$groups_id . "'";
		$this->adb->delete($query);
		$this->updateGroupUserstoNewGroup($groups_id, 0);
	}
	
	function deleteCategoryUsers($categories_id) {
		$query = "delete pp_users, pp_users_to_categories from pp_users u, pp_users_to_categories u2c " 
				. " where u.users_id = u2c.users_id and u2c.categories_id = '" . (int)$categories_id . "'";
		$this->adb->delete($query);
		$this->updateCategoryUserstoNewCategory($categories_id, 0);
	}
	
	function setUsersStatus($users_ids, $status = 1) {
		if( is_array($users_ids) ) {
			if( sizeof($users_ids) > 30 ) {
				foreach($users_ids as $k => $users_id) {
					$this->adb->update("update pp_users set users_status = '" . (int)$status . "' where users_id = '" . (int)$users_id . "'");
				}
			} else {
				$query_ids = "'" . implode("', '", array_values($users_ids)) . "'";
				$this->adb->update("update pp_users set users_status = '" . (int)$status . "' where users_id in (" . $query_ids . ")");
			}
		}
	}
	
	//address
	function addAddress($users_id, $data_array) {
		$data_array = func_db_input($data_array);
		
		$query = "insert into pp_users_address set users_id = '" . (int)$users_id 
											. "', address_type = '" . $data_array['address_type'] 
											. "', address_name = '" . $data_array['address_name'] 
											
											. "', address_email_address = '" . $data_array['address_email_address'] 
											. "', address_firstname = '" . $data_array['address_firstname'] 
											. "', address_lastname = '" . $data_array['address_lastname'] 
											. "', address_contactname = '" . $data_array['address_contactname'] 
											
											. "', address_company = '" . $data_array['address_company'] 
											. "', address_telephone = '" . $data_array['address_telephone'] 
											. "', address_fax = '" . $data_array['address_fax'] 
											. "', address_mobile = '" . $data_array['address_mobile'] 
											
											. "', address_address = '" . $data_array['address_address'] 
											. "', address_suburb = '" . $data_array['address_suburb'] 
											. "', address_postcode = '" . $data_array['address_postcode'] 
											. "', address_city = '" . $data_array['address_city'] 
											. "', address_state = '" . $data_array['address_state'] 
											. "', address_zones_id = '" . (int)$data_array['address_zones_id'] 
											. "', address_country = '" . $data_array['address_country'] 
											. "', address_countries_id = '" . (int)$data_array['address_countries_id'] 
											. "'"
											;
		$address_id = $this->adb->insert($query);
		
		return $address_id;
	}
	
	function addUserAddress($users_id, $data_array) {
		$data_array = func_db_input($data_array);
						
		$address_date_array = array(
					'users_id' => $users_id,
					'address_type' => $data_array['address_type'],
					'address_name' => $data_array['address_name'],
					
					'address_contactname' => $data_array['address_contactname'],
					'address_firstname' => $data_array['address_firstname'],
					'address_lastname' => $data_array['address_lastname'],
					'address_email_address' => $data_array['address_email_address'],
					
					'address_company' => $data_array['address_company'],
					'address_telephone' => $data_array['address_telephone'],
					'address_fax' => $data_array['address_fax'],
					'address_mobile' => $data_array['address_mobile'],
					
					'address_address' => $data_array['address_address'],
					'address_suburb' => $data_array['address_suburb'],
					'address_postcode' => $data_array['address_postcode'],
					'address_city' => $data_array['address_city'],
					'address_state' => $data_array['address_state'],
					'address_zones_id' => (int)$data_array['address_zones_id'],
					'address_country' => $data_array['address_country'],
					'address_countries_id' => (int)$data_array['address_countries_id'],
					
					'address_date_added' => 'now()',
					'address_added_by' => $this->_get_current_user(),
					'address_status' => '1',
						);
		$address_id = $this->adb->insertA('pp_users_address', $address_date_array);
		
		return $address_id;
	}
	
	function setDefaultAddress($address_id, $address_type = 'shipping', $users_id = 0) {
		if( $users_id == 0 ) {
			$users_id = $this->_get_current_user();
		}
		$params = "users_id = '" . (int)$users_id . "'";
		$data_array = array();
		if( $address_type == 'shipping' ) {
			$data_array['users_default_shipping_address'] = (int)$address_id;
		} elseif( $address_type == 'billing' ) {
			$data_array['users_default_billing_address'] = (int)$address_id;
		} elseif( $address_type == 'address' ) {
			$data_array['users_default_address'] = (int)$address_id;
		} else {
			return false;
		}
		
		return $this->adb->updateA('pp_users', $data_array, $params);
	}
	
	function updateAddress($address_id, $data_array, $users_id = 0) {
		if( $users_id == 0 ) {
			$users_id = $this->_get_current_user();
		}
		
		return $this->adb->updateA('pp_users_address', $data_array, "address_id = '" . (int)$address_id . "' and users_id = '" . (int)$users_id . "'");
	}
	
	//price types
	function getUserPriceTypes($users_id = 0, $categories_id = 0) {
		if( $users_id == 0 ) {
			$users_id = $this->_get_current_user();
		}
		$pts = array();
		$query = "select * from pp_users_prices where users_id = '" . (int)$users_id . "'";
		$rows = $this->adb->getRows($query);
		for($i=0, $n=sizeof($rows); $i<$n; $i++) {
			$pts[$rows[$i]['categories_id']] = $rows[$i]['prices_type'];
		}
		if( $categories_id > 0 ) {
			if( isset($pts[$categories_id]) ) {
				return $pts[$categories_id];
			}
			return 0;
		}
		
		return $pts;
	}
	
	//discount
	function getUserDiscount($users_id = 0, $ucid = 0, $dsct = 0) {
		if( $dsct > 0 ) {
			return $dsct;
		}
		//
		if( $users_id == 0 && $ucid == 0 ) {
			if( $this->_get_current_user() > 0 ) {
				return $this->getCurrentUserDiscount();
				
				//
				$users_id = $this->_get_current_user();
				
				//$uc = $this->getUserCategory($users_id);
				//if( $uc['categories_id'] > 0 && $uc['categories_discount'] > 0 ) {
				//	return $uc['categories_discount'];
				//}
				return $this->getUserCategoryDiscount($users_id, $ucid);
			}
		} elseif( $ucid == 0 ) {
			if( $users_id > 0 ) {
				$user = $this->getUser($users_id);
				if( $user['users_discount'] > 0 ) {
					return $user['users_discount'];
				}
			}
			$uc = $this->getUserCategory($users_id);
			if( $uc['categories_id'] > 0 && $uc['categories_discount'] > 0 ) {
				return $uc['categories_discount'];
			}
		} elseif( $users_id == 0 ) {
			$this->loadclass('user.category.class.php');
			$ucObj = new UserCategoryBase();
			$uc = $ucObj->getCategory($ucid);
			if( $uc['categories_id'] > 0 && $uc['categories_discount'] > 0 ) {
				return $uc['categories_discount'];
			}
		}
		
		return 0;
	}
	
	function getUserCategoryDiscount($users_id, $ucid) {
		$user = $this->getUser($users_id);
		if( $user['users_id'] > 0 ) {
			if( $user['users_discount'] > 0 ) {
				return $user['users_discount'];
			}
			$uc = $this->getUserCategory($users_id);
			if( $uc['categories_id'] > 0 && $uc['categories_discount'] > 0 ) {
				return $uc['categories_discount'];
			}
		}
		
		return 0;
	}
	
	//log
	function addUserLog($log_action_name, $log_action_id = '', $users_id = '') {
		static $_ulogObj;
		if( !is_object($_ulogObj)) {
			include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'user.log.class.php');
			$_ulogObj = new UserLogBase();
		}
		$_ulogObj->addLog($log_action_name, $log_action_id);
	}
	
	function addLog($log_action_name, $log_action_id = '') {
		static $_ulogObj;
		if( !is_object($_ulogObj)) {
			include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'user.log.class.php');
			$_ulogObj = new UserLogBase();
		}
		$_ulogObj->addLog($log_action_name, $log_action_id);
	}
	
	//group
	function getUserGroup($users_id) {
		return $this->adb->getRow("select ug.* from pp_users_groups ug, pp_users_to_groups u2g where ug.groups_id = u2g.groups_id and u2g.users_id = '" . (int)$users_id . "'");
	}
	
	function getUserGroups($users_id) {
		return $this->adb->getRows("select ug.* from pp_users_groups ug, pp_users_to_groups u2g where ug.groups_id = u2g.groups_id and u2g.users_id = '" . (int)$users_id . "'");
	}
	
	function getUserGroupID($users_id) {
		$row = $this->adb->getRow("select * from pp_users_to_groups where users_id = '" . (int)$users_id . "'");
		
		return $row['groups_id'];
	}
	
	function getUserGroupCode($users_id) {
		$row = $this->getUserGroup($users_id);
		
		return $row['groups_code'];
	}
	
	function addUserGroup($users_id, $groups_id) {
		return $this->adb->add("replace into pp_users_to_groups (users_id, groups_id, date_added) values ('" . (int)$users_id . "', '" . (int)$groups_id . "', now())");
	}	
	
	function updateUserGroup($users_id, $groups_id) {
		return $this->adb->update("update pp_users_to_groups set groups_id = '" . (int)$groups_id . "' where users_id = '" . (int)$users_id . "'");
	}
	
	//category
	function getUserCategory($users_id) {
		return $this->adb->getRow("select uc.* from pp_users_categories uc, pp_users_to_categories u2c where users_id = '" . (int)$users_id . "' and uc.categories_id = u2c.categories_id");
	}
	
	function getUserCategoryID($users_id) {
		$row = $this->adb->getRow("select * from pp_users_to_categories where users_id = '" . (int)$users_id . "'");
		
		return $row['categories_id'];
	}
	
	function getUserCategoryCode($users_id) {
		$row = $this->getUserCategory($users_id);
		
		return $row['categories_code'];
	}
	
	function addUserCategory($users_id, $categories_id) {
		return $this->adb->update("replace into pp_users_to_categories (users_id, categories_id, date_added) values ('" . (int)$users_id . "', '" . (int)$categories_id . "', now())");
	}
	
	function updateUserCategory($users_id) {
		return $this->adb->update("replace into pp_users_to_categories (users_id, categories_id, last_modified) values ('" . (int)$users_id . "', '" . (int)$categories_id . "', now())");
	}
	
	function deleteUserCategory($users_id, $categories_id) {
		return $this->adb->delete("delete from pp_users_to_categories where users_id = '" . (int)$users_id . "' and categories_id = '" . (int)$categories_id . "'");
	}
	
	//USERS
	function getUsers($filter = '', $check = 1, $limit = true) {
		return $this->getUsersDetail($filter, $check, $limit);
	}
	
	function getUsersIDs($filter, $check = 1, $limit = true) {
		$users = $this->getUsers($filter, $check, $limit, 'id', 'asc');
		
		return $this->getListKey($users, 'users_id');
	}
	
	function getUsersTotal($filter = '', $check = 1) {
		return $this->getUsersDetail($filter, $check, false, '', '', true);
	}
	
	function getUsersDetail($filter = '', $check = 1, $limit = true, $order_by = '', $order_sort = '', $get_total = false) {
		//
		$query_group = 0;
		$query_category = 0;
		$query_str = "";
		//
		if( is_array($filter) ) {
			if( $check == -1 ) {
				//
			} else {
				$filter['status'] = $check;
			}
		} else {
			if( $check == -1 ) {
				//
			} else {
				$filter = array();
				$filter['status'] = $check;
			}
		}
		//
		if( is_array($filter) ) {
			$filter = func_db_input($filter);
			if( isset($filter['keyword']) && $this->_not_null($filter['keyword']) == true ) {
				if( is_numeric($filter['keyword']) && $filter['keyword'] > 0 ) {
					$query_str .= " and u.users_id = '" . $filter['keyword'] . "' ";
				} else {
					$query_str .= " and ( ";
					$query_str .= " u.users_name like '%" . $filter['keyword'] . "%' or u.users_email_address like '%" . $filter['keyword'] . "%' or ";
					$query_str .= " u.users_contactname like '%" . $filter['keyword'] . "%' or ";
					$query_str .= " u.users_firstname like '%" . $filter['keyword'] . "%' or u.users_lastname like '%" . $filter['keyword'] . "%' ";
					$query_str .= " )";
				}
			}
			if( isset($filter['type']) && $this->_not_null($filter['type']) == true ) {
				$query_str .= " and u.users_type = '" . $filter['type'] . "' ";
			}
			if( isset($filter['status']) ) {
				if( is_array($filter['status']) ) {
					$query_str .= " and u.users_status in (" . $this->_implode(', ', $filter['status']) . ") ";
				} else {
					$query_str .= " and u.users_status = '" . $filter['status'] . "' ";
				}
			}
			if( isset($filter['group']) && $this->_not_null($filter['group']) == true ) {
				$query_group = 1;
				if( is_array($filter['group']) ) {
					$query_str .= " and u.users_id = u2g.users_id and u2g.groups_id in (" . $this->_implode(', ', $filter['group']) . ") ";
				} else {
					$query_str .= " and u.users_id = u2g.users_id and u2g.groups_id = '" . (int)$filter['group'] . "' ";
				}
			}
			if( isset($filter['nogroup']) && $this->_not_null($filter['nogroup']) == true ) {
				$query_group = 2;
				$query_str .= " and u.users_id = u2g.users_id and u2g.groups_id = '0' ";
			}
			if( isset($filter['category']) && $this->_not_null($filter['category']) == true ) {
				$query_category = 1;
				if( is_array($filter['category']) ) {
					$query_str .= " and u.users_id = u2c.users_id and u2c.categories_id in (" . $this->_implode(', ', $filter['category']) . ") ";
				} else {
					$query_str .= " and u.users_id = u2c.users_id and u2c.categories_id = '" . (int)$filter['category'] . "' ";
				}
			}
			if( isset($filter['nocategory']) && $this->_not_null($filter['nocategory']) == true ) {
				$query_category = 2;
				$query_str .= " and u.users_id = u2c.users_id and u2c.categories_id = '0' ";
			}			
			if( isset($filter['ids']) && $this->_not_null($filter['ids']) == true ) {
				if( is_array($filter['ids']) ) {
					$query_str .= " and u.users_id in (" . $this->_implode(', ', $filter['ids']) . ") ";
				} else {
					$query_str .= " and u.users_id = '" . (int)$filter['ids'] . "' ";
				}
			}
			if( isset($filter['idstart']) ) {
				$query_str .= " and u.users_id > '" . (int)$filter['idstart'] . "' ";
			}
			if( isset($filter['idend']) ) {
				$query_str .= " and u.users_id < '" . (int)$filter['idend'] . "' ";
			}
			if( isset($filter['fields']) && is_array($filter['fields']) ) {
				$qt = $this->_get_query_type();
				foreach($filter['fields'] as $k => $v) {
					$t = '';
					if( strpos($k, ':') !== false ) {
						$ks = explode(':', $k);
						$k = $ks['0'];
						$t = $ks['1'];
					}
					if( !in_array($t, $qt) ) {
						$t = '';
					}
					if( in_array($t, array('=', '>', '>=', '<', '<=', '!=')) ) {
						$query_str .= " and u." . $k . " " . $t . " " . (int)$v . " ";
					} else {
						$query_str .= " and u." . $k . " = '" . (int)$v . "' ";
					}
				}
			}
		}
		//
		$query_order_str = $this->_get_query_order_str($order_by, $order_sort);
		//
		$query_limit_str = "";
		if( $limit == true ) {
			$query_limit_str = $this->getQueryLimitStr();
		}
		//
		if( $get_total == true ) {
			if( $query_group == 2 ) {//nogroup
				$query = "select count(*) as count from pp_users u, pp_users_to_groups u2g ";
				if( $query_category > 0 ) {
					$query .= ", pp_users_to_categories u2c ";
				}
				$query .= " where 1 ";
			} elseif( $query_group == 1 ) {
				//$query = "select count(*) as count from pp_users u, pp_users_groups ug, pp_users_to_groups u2g where 1 ";
				$query = "select count(*) as count from pp_users u left join pp_users_to_groups u2g on u.users_id = u2g.users_id " 
						. " left join pp_users_groups ug on u2g.groups_id = ug.groups_id ";
				if( $query_category > 0 ) {
					$query .= " left join pp_users_to_categories u2c on u.users_id = u2c.users_id " 
							. " left join pp_users_categories ug on u2c.categories_id = ug.categories_id ";
				}
				$query .= " where 1 ";
			} else {
				$query = "select count(*) as count from pp_users u ";
				if( $query_category > 0 ) {
					$query .= " left join pp_users_to_categories u2c on u.users_id = u2c.users_id " 
							. " left join pp_users_categories ug on u2c.categories_id = ug.categories_id ";
				}
				$query .= " where 1 ";
			}
			$query .= $query_str;
			
			return $this->adb->getCount($query);
		} else {
			if( $query_group == 2 ) {//nogroup
				$query = "select u.* from pp_users u, pp_users_to_groups u2g ";
				if( $query_category > 0 ) {
					$query .= ", pp_users_to_categories u2c ";
				}
				$query .= " where 1 ";
				$query .= $query_str . $query_order_str . $query_limit_str;
			} elseif( $query_group == 1 ) {
				//$query = "select u.*, ug.* from pp_users u, pp_users_groups ug, pp_users_to_groups u2g where 1 ";
				$query = "select u.*, ug.* from pp_users u left join pp_users_to_groups u2g on u.users_id = u2g.users_id " 
						. " left join pp_users_groups ug on u2g.groups_id = ug.groups_id ";
				if( $query_category > 0 ) {
					$query .= " left join pp_users_to_categories u2c on u.users_id = u2c.users_id " 
							. " left join pp_users_categories ug on u2c.categories_id = ug.categories_id ";
				}
				$query .= " where 1 ";
				$query .= $query_str . $query_order_str . $query_limit_str;
			} else {
				$query = "select u.* from pp_users u ";
				if( $query_category > 0 ) {
					$query .= " left join pp_users_to_categories u2c on u.users_id = u2c.users_id " 
							. " left join pp_users_categories ug on u2c.categories_id = ug.categories_id ";
				}
				$query .= " where 1 ";
				$query .= $query_str . $query_order_str . $query_limit_str;
			}
			
			$rows = array();
			$result = $this->adb->query($query);
			while($row = $this->adb->fetch_array($result)) {
				unset($row['users_password']);
				$rows[] = $row;
			}
			
			return $rows;
		}
	}
	
	//default
	//$order_by = 'date_added'
	//$order_sort = 'desc'
	function _get_query_order_str($order_by = '', $order_sort = '') {
		if( $order_by == '' ) {
			$order_by = $this->query_order_by;
		}
		if( $order_sort == '' ) {
			$order_sort = $this->query_order_sort;
		}
		if( $order_by == '' && $order_sort == '' ) {
			$order_by = 'users_name';
			$order_sort = 'asc';
		}
		if( $order_sort != 'desc' ) {
			$order_sort = 'asc';
		}
		if( $order_by == 'id' ) {
			$query_order_str = " order by u.users_id " . $order_sort;
		} elseif( $order_by == 'name' ) {
			$query_order_str = " order by u.users_name " . $order_sort;
		} elseif( $order_by == 'firstname' ) {
			$query_order_str = " order by u.users_firstname " . $order_sort;
		} elseif( $order_by == 'lastname' ) {
			$query_order_str = " order by u.users_lastname " . $order_sort;
		} elseif( $order_by == 'email' || $order_by == 'email_address' ) {
			$query_order_str = " order by u.users_email_address " . $order_sort;
		} elseif( $order_by == 'company' ) {
			$query_order_str = " order by u.users_company " . $order_sort;
		} elseif( $order_by == 'date_added' || $order_by == 'dateadded' ) {
			$query_order_str = " order by u.users_id " . $order_sort;
		} elseif( $order_by == 'status' ) {
			$query_order_str = " order by u.users_status " . $order_sort;
		} elseif( $order_by == 'creditline' ) {
			$query_order_str = " order by u.users_creditline " . $order_sort;
		} elseif( $order_by == 'creditused' ) {
			$query_order_str = " order by u.users_creditused " . $order_sort;
		} elseif( $order_by == 'receivables' ) {
			$query_order_str = " order by u.users_receivables " . $order_sort;
		} elseif( $order_by == 'discount' ) {
			$query_order_str = " order by u.users_discount " . $order_sort;
		} else {
			$query_order_str = " order by u.users_id " . $order_sort;
		}
		
		return $query_order_str;
	}
	
	//private
	function _get_session_id() {
		global $sessionObj;
		
		if( $sessionObj->session_id ) {
			$sid = $sessionObj->session_id;
		} else {
			$sid = $GLOBALS['PPSID'];
			//$sid = $_COOKIE['PPSID'];
		}
		
		return $sid;
	}
	
	function _encryption_password($value) {
		include_once(CONFIG_PATH . CONFIG_DIR_FUNCTIONS . 'password_funcs.function.php');
		
		return func_encrypt_password($value);
	}
	
	function _validate_password($plain, $encrypted) {
		include_once(CONFIG_PATH . CONFIG_DIR_FUNCTIONS . 'password_funcs.function.php');
		
		return func_validate_password($plain, $encrypted);
	}
	
	function _generate_password() {
		include_once(CONFIG_PATH . CONFIG_DIR_FUNCTIONS . 'password_funcs.function.php');
		
		return func_make_password();
	}
	
	function _get_query_type() {
		$query_type = array(
				'=', '>', '>=', '<', '<=', '!=',
				'like', 'notlike', '%like%', '%like', 'like%',
				'regexp', 'notregexp',
					);
		return $query_type;
	}
	
	function _generate_account($id) {
		$a = $id;
		$m = array(
			'0' => '0',
			'1' => 'A', '2' => 'B', '3' => 'C', '4' => 'D', '5' => 'E', '6' => 'F', '7' => 'G',
			'8' => 'H', '9' => 'I', '10' => 'J', '11' => 'K', '12' => 'L', '13' => 'M', '14' => 'N',
			'15' => 'O', '16' => 'P', '17' => 'Q', '18' => 'R', '19' => 'S', '20' => 'T',
			'21' => 'U', '22' => 'V', '23' => 'W', '24' => 'X', '25' => 'Y', '26' => 'Z');
		//$a = str_pad($id, 10, '1', STR_PAD_LEFT);
		for($i=0, $n=strlen($a); $i<$n; $i++) {
			if( substr($a, $i, 1) > 0 && substr($a, $i, 1) <= 2 && ($i + 1 < $n) && intval(substr($a, $i, 2)) < 27 ) {
				$c = intval(substr($a, $i, 2));
				$i++;
			} else {
				$c = intval(substr($a, $i, 1));
			}
			$ss[] = $m[$c];
		}
		$s = implode('', $ss);
		$s .= '1' . $m[strlen($a)] . $m[strlen($s)];
		$s = str_pad($s, 6, '2', STR_PAD_RIGHT);
		
		return $s;
	}
	
	function _update_account($users_id) {
		$s = $this->_generate_account($users_id);
		
		$this->adb->update("update pp_users set users_name = '" . $s . "' where users_id = '" . (int)$users_id . "'");
	}
	
	//CC
	function getUserCreditCard($address_id, $users_id = 0) {
		if( $users_id == 0 ) {
			$users_id = $this->_get_current_user();
		}
		if( $address_id > 0 ) {
			$address = $this->getUserAddress($users_id, $address_id);
			if( $address['address_card_number'] != '' ) {
				$address['status'] = 1;
				
				return $address;
			}
		}
		
		$address = array();
		$address['status'] = 0;
		
		return $address;
		
		//
		include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'user.checkout.class.php');
		$ucObj = new UserCheckoutBase();
		$ucObj->owner = $users_id;
		
		return $ucObj->getItems();
	}
	
	//bind
	function bindItemsUsers($items) {
		$users_ids = $this->getListKey($items, 'users_id');
		if( is_array($users_ids) ) {
			$users = $this->getUsers(array('ids' => $users_ids), -1, false);
			$users = $this->setListKey($users, 'users_id');
			for($i=0, $n=sizeof($items); $i<$n; $i++) {
				$items[$i] = array_merge($items[$i], $users[$items[$i]['users_id']]);
			}
		}
		
		return $items;
	}
	
	function bindItemsUsersAddress($items, $type = 'address') {
		$users_ids = $this->getListKey($items, 'users_id');
		if( is_array($users_ids) ) {
			$addresses = $this->getUsersAddress($users_ids, $type);
			$addresses = $this->setListKey($addresses, 'users_id');
			for($i=0, $n=sizeof($items); $i<$n; $i++) {
				$items[$i] = array_merge($items[$i], $addresses[$items[$i]['users_id']]);
			}
		}
		
		return $items;
	}
	
	//format
	function _format_handler($user) {
		//
		if( CONST_USER_FIELDS_ENABLED == '1' ) {
			include_once(CONFIG_PATH . CONFIG_DIR_CLASSES . 'user.field.class.php');
			$ufieldObj = new UserFieldBase();
			$ufieldObj->bindUserFields($user);
		}
		
		return $user;
	}
	
	function getFormatUser($users_id = 0) {
		$user = $this->getUser($users_id);
		$user = $this->_format_handler($user);
		
		return $user;
	}
}
//
?>